#include "stdafx.h"
#include "net/StreamSocket.hpp"
#include "net/StreamSocketImpl.hpp"

NET_NAMESPACE_BEGIN

CStreamSocket::CStreamSocket() : CSocket(new CStreamSocketImpl)
{
}

CStreamSocket::CStreamSocket(const CSocketAddress& address) : CSocket(new CStreamSocketImpl(address.family()))
{
	connect(address);
}

CStreamSocket::CStreamSocket(CIPAddress::Family family) : CSocket(new CStreamSocketImpl(family))
{
}

CStreamSocket::CStreamSocket(const CSocket& socket) : CSocket(socket)
{
	if (!dynamic_cast<CStreamSocketImpl*>(impl()))
		throw InvalidArgumentException("Cannot assign incompatible socket");
}

CStreamSocket::CStreamSocket(CSocketImpl* pImpl) : CSocket(pImpl)
{
	if (!dynamic_cast<CStreamSocketImpl*>(impl()))
		throw InvalidArgumentException("Cannot assign incompatible socket");
}

CStreamSocket::~CStreamSocket()
{
}

CStreamSocket& CStreamSocket::operator = (const CSocket& socket)
{
	if (dynamic_cast<CStreamSocketImpl*>(socket.impl()))
		CSocket::operator = (socket);
	else
		throw InvalidArgumentException("Cannot assign incompatible socket");
	return *this;
}

void CStreamSocket::connect(const CSocketAddress& address)
{
	impl()->connect(address);
}

void CStreamSocket::connect(const CSocketAddress& address, const CTimeSpan& timeout)
{
	impl()->connect(address, timeout);
}

void CStreamSocket::connectNB(const CSocketAddress& address)
{
	impl()->connectNB(address);
}

void CStreamSocket::shutdownReceive()
{
	impl()->shutdownReceive();
}

void CStreamSocket::shutdownSend()
{
	impl()->shutdownSend();
}

void CStreamSocket::shutdown()
{
	impl()->shutdown();
}

int CStreamSocket::sendBytes(const void* buffer, int length, int flags)
{
	return impl()->sendBytes(buffer, length, flags);
}

//int CStreamSocket::sendBytes(FIFOBuffer& fifoBuf)
//{
//	ScopedLock<Mutex> l(fifoBuf.mutex());
//
//	int ret = impl()->sendBytes(fifoBuf.begin(), (int) fifoBuf.used());
//	if (ret > 0) fifoBuf.drain(ret);
//	return ret;
//}
int CStreamSocket::receiveBytes(void* buffer, int length, int flags)
{
	return impl()->receiveBytes(buffer, length, flags);
}
//
//int StreamSocket::receiveBytes(FIFOBuffer& fifoBuf)
//{
//	ScopedLock<Mutex> l(fifoBuf.mutex());
//
//	int ret = impl()->receiveBytes(fifoBuf.next(), (int)fifoBuf.available());
//	if (ret > 0) fifoBuf.advance(ret);
//	return ret;
//}

void CStreamSocket::sendUrgent(unsigned char data)
{
	impl()->sendUrgent(data);
}
NET_NAMESPACE_END
